package com.link.base.base.order.service;

import com.link.base.base.order.model.OrderPolicyResult;
import com.link.base.base.order.model.SaleOrder;
import com.link.base.base.order.model.SaleOrderItem;
import com.link.base.base.policy.model.*;
import com.link.base.base.policy.service.*;
import com.link.base.base.policy.model.*;
import com.link.base.base.policy.service.*;
import com.link.base.base.product.model.PriceListItem;
import com.link.base.base.product.service.PriceListItemService;
import com.link.core.cllog.LCLogger;
import com.link.core.basic.service.ServiceException;
import com.link.core.basic.service.KeyGenerateService;
import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author unknown
 * @date unknown
 * @comments 定单政策服务
 */
@Service
public class OrderPolicyServiceImpl implements OrderPolicyService {

    @Resource
    private PolicyService policyService;

    @Resource
    private PcyRuleService pcyRuleService;

    @Resource
    private PcyCndService pcyCndService;

    @Resource
    private PcyResultService pcyResultService;

    @Resource
    private OrderPolicyResultService orderPolicyResultService;

    @Resource
    private KeyGenerateService keyGenerateService;

    @Resource
    private PcyrltProdService pcyrltProdService;

    @Resource
    private SaleOrderItemService saleOrderItemService;

    @Resource
    private PcyCndprodService pcyCndprodService;

    @Resource
    private PriceListItemService priceListItemService;

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void applyPolicyOne(SaleOrder saleOrder) throws Exception {
        try {
            //0、查询当前订单行信息
            List<SaleOrderItem> orderItemList = saleOrderItemService.querylistByOrderId(saleOrder.getId(), "Common Item");

            //1、计算政策列表
            List<Policy> policyList = queryValidPolicyList(saleOrder);

            //2、计算政策规则、政策条件、政策结果
            List<PcyRule> ruleList = queryValidPolicyRuleList(policyList);
            List<PcyRule> satisfyRuleList = new ArrayList<PcyRule>();
            for (int ruleIndex = 0; ruleList != null && ruleIndex < ruleList.size(); ruleIndex++) {

                //3.1取出该规则下所有条件产品信息
                PcyRule currentRule = ruleList.get(ruleIndex);
                Map<Long, Map<Long, PcyCndprod>> cndCndProdMap = queryCndProdByRule(currentRule);

                //3、遍历该规则下所有条件
                List<PcyCnd> cndList = ruleList.get(ruleIndex).getConditionList();
                List<PcyCnd> satisfyCndList = new ArrayList<PcyCnd>();

                for (int cndIndex = 0; cndList != null && cndIndex < cndList.size(); cndIndex++) {
                    PcyCnd currentCnd = cndList.get(cndIndex);
                    //3.1取出该条件下所有产品
                    Map<Long, PcyCndprod> cndProdMap = cndCndProdMap.get(currentCnd.getId());

                    //3.2 判断当前条件的满足情况
                    checkCurrentCondition(currentCnd, orderItemList, cndProdMap);

                    if ("Y".equals(currentCnd.getSatisfyStatus())) {
                        satisfyCndList.add(currentCnd);
                    }


                }

                //3.3 对比当前规则下，所有满足条件。将结果记录下来
                Double maxNum = 0d;
                Double minNum = 999999d;
                Double satisfyNum = 0d;
                String satisfyComments = "";
                for (int i = 0; i < satisfyCndList.size(); i++) {
                    if (maxNum < satisfyCndList.get(i).getSatisfyNumber()) {
                        maxNum = satisfyCndList.get(i).getSatisfyNumber();
                        satisfyComments = satisfyCndList.get(i).getSatisfyComments();
                    }
                    if (minNum > satisfyCndList.get(i).getSatisfyNumber()) {
                        minNum = satisfyCndList.get(i).getSatisfyNumber();
                    }
                    satisfyNum++;
                }
                if (satisfyNum > 0) {
                    currentRule.setSatisfyNumber(maxNum);
                    currentRule.setSatisfyStatus("Y");
                    currentRule.setSatisfyComments(satisfyComments);
                    satisfyRuleList.add(currentRule);
                }
            }

            //4、更新最新的政策结果到订单行
            updatePolicyRuleToOrder(satisfyRuleList, saleOrder);


        } catch (Exception e) {
            LCLogger.withException(e);
            throw new ServiceException("ORDER-008",e.getMessage());
        }
    }

    /**
     * 更新最新的政策规则到订单行
     *
     * @param satisfyRuleList
     */
    private void updatePolicyRuleToOrder(List<PcyRule> satisfyRuleList, SaleOrder order) throws Exception {
        List<OrderPolicyResult> newList = new ArrayList<OrderPolicyResult>();
        List<OrderPolicyResult> deleteList = new ArrayList<OrderPolicyResult>();
        List<OrderPolicyResult> updateList = new ArrayList<OrderPolicyResult>();


        //根据订单ID查询历史政策规则
        List<OrderPolicyResult> orderPolicyResultList = orderPolicyResultService.queryListByOrderId(order.getId());
        Map<Long, PcyRule> map = new HashMap<Long, PcyRule>();
        for (int i = 0; satisfyRuleList != null && i < satisfyRuleList.size(); i++) {
            map.put(satisfyRuleList.get(i).getId(), satisfyRuleList.get(i));
        }
        for (int i = 0; orderPolicyResultList != null && i < orderPolicyResultList.size(); i++) {
            OrderPolicyResult orderPolicyResult = orderPolicyResultList.get(i);
            if (map.get(orderPolicyResult.getPolicyRuleId()) != null) {
                PcyRule pcyRule = map.get(orderPolicyResult.getPolicyRuleId());
                orderPolicyResult.setResultDesc(pcyRule.getSatisfyComments());
                orderPolicyResult.setApplyNum(pcyRule.getSatisfyNumber());
                updateList.add(orderPolicyResult);
                map.remove(pcyRule.getId());
            } else {
                deleteList.add(orderPolicyResult);
            }
        }
        Iterator<Map.Entry<Long, PcyRule>> it = map.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<Long, PcyRule> entry = it.next();
            OrderPolicyResult orderPolicyResult = new OrderPolicyResult();
            orderPolicyResult.setPolicyRuleId(entry.getValue().getId());
            orderPolicyResult.setOrderId(order.getId());
            orderPolicyResult.setApplyNum(entry.getValue().getSatisfyNumber());
            orderPolicyResult.setResultDesc(entry.getValue().getSatisfyComments());
            orderPolicyResult.setApplyFlag("N");
            newList.add(orderPolicyResult);
        }

        //更新订单上产品信息
        List<OrderPolicyResult> lastRuleList = new ArrayList<OrderPolicyResult>();
        lastRuleList.addAll(newList);
        lastRuleList.addAll(updateList);
        updateOrderProduct(order, lastRuleList, satisfyRuleList);

        //更新订单上产品规则信息；（先更新产品信息，以确定该规则是否能被应用）
        for (int i = 0; i < newList.size(); i++) {
            OrderPolicyResult orderPolicyResult = newList.get(i);
            orderPolicyResult.setId(keyGenerateService.keyGenerate());
            orderPolicyResultService.insert(orderPolicyResult);

        }
        for (int i = 0; i < deleteList.size(); i++) {
            orderPolicyResultService.deleteById(deleteList.get(i));
        }
        for (int i = 0; i < updateList.size(); i++) {
            orderPolicyResultService.update(updateList.get(i));
        }
    }

    /**
     * 遍历所有的政策结果，更新、新增订单行、删除不匹配的订单行信息
     *
     * @param order
     * @param lastRuleList
     * @param satisfyRuleList
     */
    private void updateOrderProduct(SaleOrder order, List<OrderPolicyResult> lastRuleList, List<PcyRule> satisfyRuleList) throws Exception {
        List<SaleOrderItem> orderItemList = saleOrderItemService.querylistByOrderId(order.getId(), "!Common Item");
        //订单规则ID+产品ID为Key的，MAP对象
        Map<String, SaleOrderItem> orderItemMap = new HashMap<String, SaleOrderItem>();
        for (int i = 0; orderItemList != null && i < orderItemList.size(); i++) {
            SaleOrderItem saleOrderItem = orderItemList.get(i);
            orderItemMap.put(saleOrderItem.getPolicyResultId() + "_" + saleOrderItem.getProdId(), saleOrderItem);
        }
        Map<Long, PcyRule> satisfyRuleMap = new HashMap<Long, PcyRule>();
        for (int i = 0; satisfyRuleList != null && i < satisfyRuleList.size(); i++) {
            satisfyRuleMap.put(satisfyRuleList.get(i).getId(), satisfyRuleList.get(i));
        }

        for (int i = 0; lastRuleList != null && i < lastRuleList.size(); i++) {
            OrderPolicyResult orderPolicyResult = lastRuleList.get(i);
            PcyRule currentRule = satisfyRuleMap.get(orderPolicyResult.getPolicyRuleId());
            if (currentRule == null) {
                throw new ServiceException("ORDER-009");
            }
            //只负责新增，更新订单行
            updatePolicyRuleProduct(order, orderItemMap, orderPolicyResult, currentRule);
        }
        //匹配完所有的政策结果后，剩下没有更新的
        Iterator<Map.Entry<String, SaleOrderItem>> it = orderItemMap.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, SaleOrderItem> entry = it.next();
            SaleOrderItem itemExample = new SaleOrderItem();
            itemExample.setHeadId(order.getId());
            itemExample.setPolicyResultId(entry.getValue().getPolicyResultId());
            itemExample.setProdId(entry.getValue().getProdId());
            saleOrderItemService.deleteByOrderRuleProdId(itemExample);
        }

    }

    /**
     * 更新订单一个政策规则下的产品信息
     *
     * @param orderItemMap
     * @param orderPolicyResult
     * @param currentRule
     */
    private void updatePolicyRuleProduct(SaleOrder order, Map<String, SaleOrderItem> orderItemMap,
                                         OrderPolicyResult orderPolicyResult, PcyRule currentRule) throws Exception {
        Map<Long, Map<Long, PcyrltProd>> ruleResultProd = queryRltProdByRule(currentRule, order);
        List<PcyResult> resultList = currentRule.getResultList();
        for (int i = 0; resultList != null && i < resultList.size(); i++) {
            PcyResult currentResult = resultList.get(i);
            Map<Long, PcyrltProd> rltProdMap = ruleResultProd.get(currentResult.getId());

            /**
             * 特价 Special Offer、特价封顶    Special Offer Limitation、特价配额 Special Offer Quota
             * 、买赠  Buy Gifts、买赠封顶  Buy Gifts Limitation、买赠配额   Buy Gifts Quota
             * 产品 Product、产品组合 Product Portfolio、产品类别  Product Category
             * 特价 Special Offer、打折    Discounts、减单价   Reduce Unit Price、数量买赠 Quantity Buy Gifts、比例买赠 Proportion Buy Gifts
             * 数量限制 Quantity Limitation、金额限制 monetary Limitation
             */
            //买赠、产品、数量买赠
            if ("Buy Gifts".equals(currentResult.getPromType())
                    && "Product".equals(currentResult.getPromObjType()) && "Quantity Buy Gifts".equals(currentResult.getPromMethod())) {
                if (rltProdMap == null) {
                    throw new ServiceException("ORDER-010",currentResult.getId().toString());
                }
                Iterator<Map.Entry<Long, PcyrltProd>> it = rltProdMap.entrySet().iterator();
                while (it.hasNext()) {
                    Map.Entry<Long, PcyrltProd> entry = it.next();
                    PcyrltProd PcyrltProd = entry.getValue();
                    if (orderItemMap.get(currentResult.getId() + "_" + PcyrltProd.getProdId()) != null) {
                        SaleOrderItem saleOrderItem = orderItemMap.get(currentResult.getId() + "_" + PcyrltProd.getProdId());
                        saleOrderItem.setProdId(PcyrltProd.getProdId());
                        Double value = orderPolicyResult.getApplyNum() * currentResult.getQty();
                        saleOrderItem.setQty(value);
                        saleOrderItem.setItemType("Gift Item");
                        //促销价
                        saleOrderItem.setPromotionPrice(entry.getValue().getPromoPrice());
                        //实际价格
                        saleOrderItem.setNetPrice(0d);
                        //手动调整价格
                        saleOrderItem.setManualPrice(0d);
                        //原价
                        saleOrderItem.setBasePrice(entry.getValue().getPrice());
                        saleOrderItem.setPolicyRuleId(currentRule.getId());
                        saleOrderItem.setPolicyResultId(currentResult.getId());
                        String policyDesc = currentRule.getSatisfyComments() + "赠送【" + PcyrltProd.getProdName() + "】" + value + "份";
                        saleOrderItem.setPolicyDesc(policyDesc);
                        saleOrderItem.setHeadId(order.getId());
                        saleOrderItemService.update(saleOrderItem);
                        orderItemMap.remove(currentResult.getId() + "_" + PcyrltProd.getProdId());
                    } else {
                        SaleOrderItem saleOrderItem = new SaleOrderItem();
                        saleOrderItem.setProdId(PcyrltProd.getProdId());
                        Double value = orderPolicyResult.getApplyNum() * currentResult.getQty();
                        saleOrderItem.setQty(value);
                        saleOrderItem.setItemType("Gift Item");
                        //促销价
                        saleOrderItem.setPromotionPrice(entry.getValue().getPromoPrice());
                        //实际价格
                        saleOrderItem.setNetPrice(0d);
                        //手动调整价格
                        saleOrderItem.setManualPrice(0d);
                        //原价
                        saleOrderItem.setBasePrice(entry.getValue().getPrice());
                        saleOrderItem.setPolicyRuleId(currentRule.getId());
                        saleOrderItem.setPolicyResultId(currentResult.getId());
                        String policyDesc = currentRule.getSatisfyComments() + "赠送【" + PcyrltProd.getProdName() + "】" + value + "份";
                        saleOrderItem.setPolicyDesc(policyDesc);
                        saleOrderItem.setHeadId(order.getId());
                        saleOrderItem.setId(keyGenerateService.keyGenerate());
                        saleOrderItemService.insert(saleOrderItem);
                    }
                    orderPolicyResult.setApplyFlag("Y");
                }
            } else if ("Buy Gifts Limitation".equals(currentResult.getPromType())) {
                //买赠封顶
                Iterator<Map.Entry<String, SaleOrderItem>> it = orderItemMap.entrySet().iterator();
                while (it.hasNext()) {
                    Map.Entry<String, SaleOrderItem> entry = it.next();
                    SaleOrderItem saleOrderItem = entry.getValue();
                    if (saleOrderItem.getPolicyResultId().equals(currentResult.getId())) {
                        it.remove();
                    }
                }
            } else if ("Special Offer Limitation".equals(currentResult.getPromType())) {
                //特价封顶
                Iterator<Map.Entry<String, SaleOrderItem>> it = orderItemMap.entrySet().iterator();
                while (it.hasNext()) {
                    Map.Entry<String, SaleOrderItem> entry = it.next();
                    SaleOrderItem saleOrderItem = entry.getValue();
                    if (saleOrderItem.getPolicyResultId().equals(currentResult.getId())) {
                        it.remove();
                    }
                }
            }
        }

    }

    /**
     * <p>查询政策规则结果下的产品，并绑定价格返回</p>
     *
     * @author Ashen
     * @param pcyRule
     * @param order
     * @return
     * @throws Exception
     */
    private Map<Long, Map<Long, PcyrltProd>> queryRltProdByRule(PcyRule pcyRule, SaleOrder order) throws Exception {
        Map<Long, Map<Long, PcyrltProd>> map = new HashMap<Long, Map<Long, PcyrltProd>>();
        String rltListStr = "";
        for (int i = 0; pcyRule != null && pcyRule.getResultList() != null && i < pcyRule.getResultList().size(); i++) {
            if (i != 0) {
                rltListStr += ",";
            }
            rltListStr += "'" + pcyRule.getResultList().get(i).getId() + "'";
        }
        if ("".equals(rltListStr)) {
            rltListStr = "'noMatchId'";
        }
        rltListStr = "(" + rltListStr + ")";
        //获取规则结果下的产品
        PcyrltProd prodExample = new PcyrltProd();
        prodExample.setPageFlag(false);
        prodExample.setAttr1(rltListStr);
        prodExample.setAttrPriceListId(order.getPriceListId());
        List<PcyrltProd> prodList = pcyrltProdService.queryByExamplePage(prodExample);

        String prodListStr = "";
        for (int i = 0; prodList != null && i < prodList.size(); i++) {
            if (i != 0) {
                prodListStr += ",";
            }
            prodListStr += "'" + prodList.get(i).getProdId() + "'";
        }
        if ("".equals(prodListStr)) {
            prodListStr = "'noMatchId'";
        }
        prodListStr = "(" + prodListStr + ")";

        //获取产品价格
        PriceListItem priceItemExample = new PriceListItem();
        priceItemExample.setPageFlag(false);
        if (order.getPriceListId() == null) {
            throw new ServiceException("ORDER-011");
        }
        priceItemExample.setHeadId(order.getPriceListId());
        priceItemExample.setAttr4(prodListStr);
        List<PriceListItem> priceItemList = priceListItemService.queryByExamplePage(priceItemExample);

        //绑定产品与价格
        Map<Long, PriceListItem> priceItemMap = new HashMap<Long, PriceListItem>();
        for (int i = 0; priceItemList != null && i < priceItemList.size(); i++) {
            priceItemMap.put(priceItemList.get(i).getProdId(), priceItemList.get(i));
        }

        for (int i = 0; prodList != null && i < prodList.size(); i++) {
            PcyrltProd prod = prodList.get(i);
            Map<Long, PcyrltProd> prodMap = map.get(prod.getResultId());
            if (prodMap == null) {
                prodMap = new HashMap<Long, PcyrltProd>();
                map.put(prod.getResultId(), prodMap);
            }
            if (priceItemMap.get(prod.getProdId()) != null) {
                PriceListItem priceListItem = priceItemMap.get(prod.getProdId());
                prod.setPrice(priceListItem.getPrice());
                prod.setPromoPrice(priceListItem.getPromoPrice());
            } else {
                prod.setPrice(-1d);
                prod.setPromoPrice(0d);
            }
            prodMap.put(prod.getProdId(), prod);
        }
        return map;
    }

    /**
     * 校验当前条件判断结果
     *
     * @param currentCnd
     * @param orderItemList
     * @param cndProdMap
     */
    private void checkCurrentCondition(PcyCnd currentCnd, List<SaleOrderItem> orderItemList,
                                       Map<Long, PcyCndprod> cndProdMap) {
        List<SaleOrderItem> satisfyList = new ArrayList<SaleOrderItem>();

        //计算当单总金额，总数量
        Double orderNum = 0d;
        Double orderAmount = 0d;
        try {
            for (int i = 0; i < orderItemList.size(); i++) {
                orderAmount += orderItemList.get(i).getAmount();
                orderNum += orderItemList.get(i).getQty();
            }
        } catch (Exception e) {
            LCLogger.withException(e);
            throw new ServiceException("ORDER-012");
        }
        //计算满足当前条件的总金额，总数量
        Double ProductNum = 0d;
        Double productAmount = 0d;
        for (int i = 0; orderItemList != null && i < orderItemList.size(); i++) {
            SaleOrderItem orderItem = orderItemList.get(i);
            if (cndProdMap != null && cndProdMap.get(orderItem.getProdId()) != null) {
                satisfyList.add(orderItem);
                productAmount += orderItem.getAmount();
                ProductNum += orderItem.getQty();
            }
        }

        //参数说明：Volume 体积
        //无 Nothing/产品  Product/
        // 整单 Whole Order
        String wholeOrder = "Whole Order";
        //数量
        String quantity = "Quantity";
        String money = "Money";
        String product = "Product";
        //产品类别 Product Category
        String productCategory = "Product Category";
        if (wholeOrder.equals(currentCnd.getCndObjType()) && quantity.equals(currentCnd.getValueType())) {
            //整单、数量判断
            Double value = orderNum / currentCnd.getCndMinimum();
            value = Double.valueOf(value.intValue());
            currentCnd.setSatisfyNumber(value);
            currentCnd.setSatisfyComments("因整单数量:" + orderNum + ",满足最小数量:" + currentCnd.getCndMinimum() + ";");
            if (value >= 1) {
                currentCnd.setSatisfyStatus("Y");
            }
        } else if (wholeOrder.equals(currentCnd.getCndObjType()) && money.equals(currentCnd.getValueType())) {
            //整单、金额判断
            Double value = orderAmount / currentCnd.getCndMinimum();
            value = Double.valueOf(value.intValue());
            currentCnd.setSatisfyNumber(value);
            currentCnd.setSatisfyComments("因整单金额:" + orderAmount + ",满足最小金额:" + currentCnd.getCndMinimum() + ";");
            if (value >= 1) {
                currentCnd.setSatisfyStatus("Y");
            }
        } else if (product.equals(currentCnd.getCndObjType()) && quantity.equals(currentCnd.getValueType())) {
            //产品、数量判断
            Double value = ProductNum / currentCnd.getCndMinimum();
            value = Double.valueOf(value.intValue());
            currentCnd.setSatisfyNumber(value);
            String prodNameListStr = "";
            for (int i = 0; i < satisfyList.size(); i++) {
                if (i != 0) {
                    prodNameListStr += "、";
                }
                prodNameListStr += "【" + satisfyList.get(i).getProdName() + "】";
            }
            currentCnd.setSatisfyComments("因购买产品" + prodNameListStr + "数量:" + ProductNum + ",满足最小数量:" + currentCnd.getCndMinimum() + ";");
            if (value >= 1) {
                currentCnd.setSatisfyStatus("Y");
            }
        } else if (product.equals(currentCnd.getCndObjType()) && money.equals(currentCnd.getValueType())) {
            //产品、金额判断
            Double value = productAmount / currentCnd.getCndMinimum();
            value = Double.valueOf(value.intValue());
            currentCnd.setSatisfyNumber(value);
            String prodNameListStr = "";
            for (int i = 0; i < satisfyList.size(); i++) {
                if (i != 0) {
                    prodNameListStr += "、";
                }
                prodNameListStr += "【" + satisfyList.get(i).getProdName() + "】";
            }
            currentCnd.setSatisfyComments("因购买产品" + prodNameListStr + "金额:" + productAmount + ",满足最小金额:" + currentCnd.getCndMinimum() + ";");
            if (value >= 1) {
                currentCnd.setSatisfyStatus("Y");
            }
        } else if (productCategory.equals(currentCnd.getCndObjType()) && quantity.equals(currentCnd.getValueType())) {
            //产品类别、金额判断

        } else if (productCategory.equals(currentCnd.getCndObjType()) && money.equals(currentCnd.getValueType())) {
            //产品类别、金额判断

        }

    }

    /**
     * 查询该条件下所有产品信息
     *
     * @param pcyRule
     * @return
     * @throws Exception
     */
    private Map<Long, Map<Long, PcyCndprod>> queryCndProdByRule(PcyRule pcyRule) throws Exception {
        Map<Long, Map<Long, PcyCndprod>> map = new HashMap<Long, Map<Long, PcyCndprod>>();
        String cndListStr = "";
        for (int i = 0; pcyRule != null && pcyRule.getConditionList() != null && i < pcyRule.getConditionList().size(); i++) {
            if (i != 0) {
                cndListStr += ",";
            }
            cndListStr += "'" + pcyRule.getConditionList().get(i).getId() + "'";
        }
        if ("".equals(cndListStr)) {
            cndListStr = "'noMatchId'";
        }
        cndListStr = "(" + cndListStr + ")";

        PcyCndprod prodExample = new PcyCndprod();
        prodExample.setPageFlag(false);
        prodExample.setAttr1(cndListStr);
        List<PcyCndprod> prodList = pcyCndprodService.queryByExamplePage(prodExample);
        for (int i = 0; prodList != null && i < prodList.size(); i++) {
            PcyCndprod prod = prodList.get(i);
            Map<Long, PcyCndprod> prodMap = map.get(prod.getCndId());
            if (prodMap == null) {
                prodMap = new HashMap<Long, PcyCndprod>();
                map.put(prod.getCndId(), prodMap);
            }
            prodMap.put(prod.getProdId(), prod);
        }
        return map;
    }

    /**
     * 根据匹配的政策列表，查询规则、条件、结果列表
     *
     * @param policyList
     * @return
     */
    private List<PcyRule> queryValidPolicyRuleList(List<Policy> policyList) throws Exception {
        if (policyList == null || policyList.size() == 0) {
            return null;
        }
        String policyIdStr = "";
        for (int i = 0; i < policyList.size(); i++) {
            if (i != 0) {
                policyIdStr += ",";
            }
            policyIdStr += "'" + policyList.get(i).getId() + "'";
        }
        if ("".equals(policyIdStr)) {
            policyIdStr = "'noMatchId'";
        }
        policyIdStr = "(" + policyIdStr + ")";

        //2、查询规则政策
        PcyRule ruleExample = new PcyRule();
        ruleExample.setPageFlag(false);
        ruleExample.setAttr1(policyIdStr);
        List<PcyRule> ruleList = pcyRuleService.queryByExamplePage(ruleExample);
        Map<Long, PcyRule> ruleMap = new HashMap<Long, PcyRule>();
        for (int i = 0; ruleList != null && i < ruleList.size(); i++) {
            ruleMap.put(ruleList.get(i).getId(), ruleList.get(i));
        }

        //3、查询政策规则下，条件信息
        PcyCnd cndExample = new PcyCnd();
        cndExample.setPageFlag(false);
        cndExample.setAttr1(policyIdStr);
        List<PcyCnd> cndList = pcyCndService.queryByExamplePage(cndExample);
        for (int i = 0; cndList != null && i < cndList.size(); i++) {
            PcyCnd pcyCnd = cndList.get(i);
            PcyRule pcyRule = ruleMap.get(pcyCnd.getRuleId());
            if (pcyRule.getConditionList() == null) {
                pcyRule.setConditionList(new ArrayList<PcyCnd>());
            }
            pcyRule.getConditionList().add(pcyCnd);
        }

        //4、查询规则条件下，政策结果信息
        PcyResult resultExample = new PcyResult();
        resultExample.setPageFlag(false);
        resultExample.setAttr1(policyIdStr);
        List<PcyResult> resultList = pcyResultService.queryByExamplePage(resultExample);
        for (int i = 0; resultList != null && i < resultList.size(); i++) {
            PcyResult pcyResult = resultList.get(i);
            PcyRule pcyRule = ruleMap.get(pcyResult.getRuleId());
            if (pcyRule.getResultList() == null) {
                pcyRule.setResultList(new ArrayList<PcyResult>());
            }
            pcyRule.getResultList().add(pcyResult);
        }

        //5、将规则下的条件排序，按容易程度排序。由易到难
        return ruleList;
    }

    /**
     * 查询当前可应用的政策列表
     *
     * @param order
     * @return
     */
    private List<Policy> queryValidPolicyList(SaleOrder order) throws Exception {
        Policy example = new Policy();
        if (order == null || order.getAcctId() == null) {
            throw new ServiceException("PUBLIC-026");
        }
        example.setPageFlag(false);
        example.setAttr1(String.valueOf(order.getAcctId()));
        return policyService.queryByExamplePage(example);
    }

    @Override
    public void applyPolicyTwo(SaleOrder order) throws Exception {
        //不需要校验第一步已经校验过的信息、校验第一步剩下的范围产品信息
        //根据订单ID查询历史政策规则
        //1、查询订单下所有的政策规则信息
        List<OrderPolicyResult> orderPolicyResultList = orderPolicyResultService.queryListByOrderId(order.getId());

        //2、校验范围产品信息
        vertifyPolicyResult(order, orderPolicyResultList);

        //3、更新产品信息
        updateOrderPolicyResult(order, orderPolicyResultList);

    }

    /**
     * 查询非常规行信息，如果订单行上政策规则ID有值，则该政策信息为应用状态。否则未应用
     *
     * @param order
     * @param orderPolicyResultList
     */
    private void updateOrderPolicyResult(SaleOrder order, List<OrderPolicyResult> orderPolicyResultList) throws Exception {
        //查询当前非常规行信息
        List<SaleOrderItem> orderItemList = saleOrderItemService.querylistByOrderId(order.getId(), "!Common Item");
        Map<Long, SaleOrderItem> orderItemMap = new HashMap<Long, SaleOrderItem>();
        for (int i = 0; orderItemList != null && i < orderItemList.size(); i++) {
            orderItemMap.put(orderItemList.get(i).getPolicyRuleId(), orderItemList.get(i));
        }

        for (int i = 0; orderPolicyResultList != null && i < orderPolicyResultList.size(); i++) {
            OrderPolicyResult orderRule = orderPolicyResultList.get(i);
            if (orderItemMap.get(orderRule.getPolicyRuleId()) != null) {
                orderRule.setApplyFlag("Y");
                orderPolicyResultService.update(orderRule);
            } else {
                orderRule.setApplyFlag("N");
                orderPolicyResultService.update(orderRule);
            }
        }

    }

    private void vertifyPolicyResult(SaleOrder order, List<OrderPolicyResult> orderPolicyResultList) throws Exception {
        //查询当前非常规行信息
        List<SaleOrderItem> orderItemList = saleOrderItemService.querylistByOrderId(order.getId(), "!Common Item");

        //查询各政策规则下结果信息
        queryResultByRuleList(orderPolicyResultList);
        Map<Long, OrderPolicyResult> orderRuleMap = new HashMap<Long, OrderPolicyResult>();
        for (int i = 0; orderPolicyResultList != null && i < orderPolicyResultList.size(); i++) {
            orderRuleMap.put(orderPolicyResultList.get(i).getPolicyRuleId(), orderPolicyResultList.get(i));
        }

        //统一校验所有的范围订单行，所在的政策规则，产品信息;通过SQL处理
        //每个规则结果金额汇总
        Map<Long, Double> resultAmount = new HashMap<Long, Double>();
        //最大金额
        Map<Long, Double> maxResultAmount = new HashMap<Long, Double>();
        //每个规则结果数量汇总
        Map<Long, Double> resultNumber = new HashMap<Long, Double>();
        //最大数量
        Map<Long, Double> maxResultNumber = new HashMap<Long, Double>();

        //对现有的订单行信息，进行汇总（规则，结果）处理
        for (int i = 0; orderItemList != null && i < orderItemList.size(); i++) {
            SaleOrderItem saleOrderItem = orderItemList.get(i);
            if (orderRuleMap.get(saleOrderItem.getPolicyRuleId()) == null) {
                throw new ServiceException("ORDER-013",saleOrderItem.getId().toString());
            }

            //校验Map
            OrderPolicyResult currentPolicyRule = orderRuleMap.get(saleOrderItem.getPolicyRuleId());
            for (int j = 0; currentPolicyRule.getResultList() != null && j < currentPolicyRule.getResultList().size(); j++) {
                PcyResult result = currentPolicyRule.getResultList().get(j);
                if (result.getId().equals(saleOrderItem.getPolicyResultId())) {
                    if ("Special Offer Limitation".equals(result.getPromType()) && "Product".equals(result.getPromObjType())) {
                        //数量限制
                        if ("Quantity Limitation".equals(result.getLimitType())) {
                            //当前订单数量
                            if (resultNumber.get(saleOrderItem.getPolicyResultId()) == null) {
                                resultNumber.put(saleOrderItem.getPolicyResultId(), saleOrderItem.getQty());
                            } else {
                                Double lastNumber = resultNumber.get(saleOrderItem.getPolicyResultId());
                                resultNumber.put(saleOrderItem.getPolicyResultId(), saleOrderItem.getQty() + lastNumber);
                            }
                            Double applayNum = orderRuleMap.get(saleOrderItem.getPolicyRuleId()).getApplyNum();
                            maxResultNumber.put(saleOrderItem.getPolicyResultId(), applayNum * result.getQty());
                        } else if ("monetary Limitation".equals(result.getLimitType())) {
                            if (resultAmount.get(saleOrderItem.getPolicyResultId()) == null) {
                                resultAmount.put(saleOrderItem.getPolicyResultId(), saleOrderItem.getAmount());
                            } else {
                                Double lastAmount = resultAmount.get(saleOrderItem.getPolicyResultId());
                                resultAmount.put(saleOrderItem.getPolicyResultId(), saleOrderItem.getAmount() + lastAmount);
                            }
                            Double applayNum = orderRuleMap.get(saleOrderItem.getPolicyRuleId()).getApplyNum();
                            maxResultAmount.put(saleOrderItem.getPolicyResultId(), applayNum * result.getQty());
                        } else {
                            throw new ServiceException("ORDER-014",result.getId().toString());
                        }
                    } else if ("Buy Gifts Limitation".equals(result.getPromType()) && "Product".equals(result.getPromObjType())) {
                        if ("Quantity Limitation".equals(result.getLimitType())) {
                            if (resultNumber.get(saleOrderItem.getPolicyResultId()) == null) {
                                resultNumber.put(saleOrderItem.getPolicyResultId(), saleOrderItem.getQty());
                            } else {
                                Double lastNumber = resultNumber.get(saleOrderItem.getPolicyResultId());
                                resultNumber.put(saleOrderItem.getPolicyResultId(), saleOrderItem.getQty() + lastNumber);
                            }
                            Double applayNum = orderRuleMap.get(saleOrderItem.getPolicyRuleId()).getApplyNum();
                            maxResultNumber.put(saleOrderItem.getPolicyResultId(), applayNum * result.getQty());
                        } else if ("monetary Limitation".equals(result.getLimitType())) {
                            if (resultAmount.get(saleOrderItem.getPolicyResultId()) == null) {
                                //resultAmount.put(saleOrderItem.getPolicyResultId(), saleOrderItem.getAmount());
                                resultAmount.put(saleOrderItem.getPolicyResultId(), saleOrderItem.getQty() * saleOrderItem.getBasePrice());

                            } else {
                                Double lastAmount = resultAmount.get(saleOrderItem.getPolicyResultId());
                                //resultAmount.put(saleOrderItem.getPolicyResultId(), saleOrderItem.getAmount()+lastAmount);
                                resultAmount.put(saleOrderItem.getPolicyResultId(),
                                        saleOrderItem.getQty() * saleOrderItem.getBasePrice() + lastAmount);

                            }
                            Double applayNum = orderRuleMap.get(saleOrderItem.getPolicyRuleId()).getApplyNum();
                            maxResultAmount.put(saleOrderItem.getPolicyResultId(), applayNum * result.getQty());
                        } else {
                            throw new ServiceException("ORDER-014",result.getId().toString());
                        }
                    }
                }
            }
        }

        Iterator<Map.Entry<Long, Double>> numberIt = resultNumber.entrySet().iterator();
        while (numberIt.hasNext()) {
            Map.Entry<Long, Double> entry = numberIt.next();
            Double selectNumber = entry.getValue();
            Double maxNumber = maxResultNumber.get(entry.getKey());
            if (selectNumber > maxNumber) {
                throw new ServiceException("ORDER-015",selectNumber.toString(),maxNumber.toString());
            }
        }
        Iterator<Map.Entry<Long, Double>> amountIt = resultAmount.entrySet().iterator();
        while (amountIt.hasNext()) {
            Map.Entry<Long, Double> entry = amountIt.next();
            Double selectAmount = entry.getValue();
            Double maxAmount = maxResultAmount.get(entry.getKey());
            if (selectAmount > maxAmount) {
                throw new ServiceException("ORDER-016",selectAmount.toString(),maxAmount.toString());
            }
        }
    }

    /**
     * 根据订单上的规则ID，查询规则下的结果列表
     * 并将结果列表放到订单政策规则下
     *
     * @param orderPolicyResultList
     * @return
     * @throws Exception
     */
    private void queryResultByRuleList(List<OrderPolicyResult> orderPolicyResultList) throws Exception {
        Map<Long, OrderPolicyResult> orderRuleMap = new HashMap<Long, OrderPolicyResult>();
        String ruleListStr = "";
        for (int i = 0; orderPolicyResultList != null && i < orderPolicyResultList.size(); i++) {
            if (i != 0) {
                ruleListStr += ",";
            }
            ruleListStr += "'" + orderPolicyResultList.get(i).getPolicyRuleId() + "'";
            orderRuleMap.put(orderPolicyResultList.get(i).getPolicyRuleId(), orderPolicyResultList.get(i));
        }
        if ("".equals(ruleListStr)) {
            ruleListStr = "'noMatchId'";
        }
        ruleListStr = "(" + ruleListStr + ")";
        PcyResult resultExample = new PcyResult();
        resultExample.setPageFlag(false);
        resultExample.setAttr2(ruleListStr);
        List<PcyResult> resultList = pcyResultService.queryByExamplePage(resultExample);
        for (int i = 0; resultList != null && i < resultList.size(); i++) {
            PcyResult result = resultList.get(i);
            if (orderRuleMap.get(result.getRuleId()) == null) {
                throw new ServiceException("订单结果记录到订单规则上为空！");
            }
            OrderPolicyResult orderRule = orderRuleMap.get(result.getRuleId());
            if (orderRule.getResultList() == null) {
                orderRule.setResultList(new ArrayList<PcyResult>());
            }
            List<PcyResult> currentRuleResultList = orderRule.getResultList();
            currentRuleResultList.add(result);
        }
    }
}
